package testtiles.object;

import java.util.ArrayList;
import java.util.Iterator;

import butines.core.math2d.Vector2D;
import butines.game.AbstractGameObject;
import butines.game.GameObject;
import butines.game.GameObjectMoving;
import butines.game.Messenger;
import butines.game.steering.ProximityDatabase;

public class Player {

	private ArrayList<Unit> units = new ArrayList<Unit>();
	private ArrayList<Unit> selected = new ArrayList<Unit>();
	private ArrayList<Unit> releasable = new ArrayList<Unit>();
	private ArrayList<Unit> selection = new ArrayList<Unit>();
	
	private UIWorld world;
	
	public Player(UIWorld world) {
		this.world = world;
	}
	
	private ProximityDatabase<GameObjectMoving> getProximityDatabase() {
		return world.getProximityDatabase();
	}
	
	private Messenger getMessenger() {
		return world.getMessenger();
	}
	
	private boolean isVisibled(AbstractGameObject o) {
		return world.isVisibled(o.getPosition().x, o.getPosition().y, o.getRadius());		
	}
	
	private boolean isInsideOfSelection(Vector2D pos, float r) {
		return world.isInsideOfSelection(pos.x, pos.y, r);
	}
		
	public ArrayList<Unit> getUnits() {
		return units;
	}
	
	public ArrayList<Unit> getSelected() {
		return selected;
	}

	public void setSelected(ArrayList<Unit> selected) {
		this.selected = selected;
	}

	public void addUnit(Unit unit) {
		unit.setMessenger(getMessenger());
		unit.setProximityDatabase(getProximityDatabase());
		if (unit.isSelected())
			selected.add(unit);
		units.add(unit);
	}

	public void removeUnit(Unit unit) {
		unit.release();
		units.remove(unit);
	}


	public void updateUnits(ArrayList<Unit> visibled, float tpf) {

		releasable.clear();
		selection.clear();
		
		for (Unit unit: units) {
			
			if (unit.isAlive() == false) {
				releasable.add(unit);
				continue;
			}
			
			unit.update(tpf);
			if (isVisibled(unit) == false) {
				continue;
			}
			
			visibled.add(unit);
			
			boolean mouseOver = isInsideOfSelection(unit.getPosition(), unit.getRadius());
			unit.setMouseOver(mouseOver);
			
			if (mouseOver) {
				selection.add(unit);
			}
			
		}

		for (Unit unit: releasable) {
			removeUnit(unit);
		}
		
	}
	
	public void deselectUnits() {
		Iterator<Unit> i = selected.iterator();
		while (i.hasNext()) {
			i.next().setSelected(false);
			i.remove();
		}
	}
	
	public void selectUnits() {
		if (selection.isEmpty() == false) {
			deselectUnits();
			for (Unit unit: selection) {
				boolean mouseOver = isInsideOfSelection(unit.getPosition(), unit.getRadius());
				unit.setMouseOver(mouseOver);
				unit.setSelected(true);
				selected.add(unit);
			}
		}
	}

	public void commandMoveUnit(int  x, int y) {
		UnitGroup group = new UnitGroup();
		for (Unit unit: selected) {
			unit.setGroup(group);
		}
		group.move(getMessenger(), new Vector2D(x, y));
	}
	
	public void commandHoldUnit() {
		for (GameObject obj: selected) {
			getMessenger().dispatch(Messages.HOLD, null, obj, 0);
		}
	}
	
}
